package com.sinosoft.ci.utils;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.LinkedList;
import java.util.List;

/**
 * zip 处理工具
 * 
 * @author 韩朝祥
 *
 */
public class ZipUtils {
	/**
	 * 将目录压缩成 zip 文件
	 * 
	 * @param srcDir
	 *            源文件目录
	 * @param destFile
	 *            目标目录
	 */
	public static void zipDir(File srcDir, File destFile) throws IOException {
		if (!srcDir.isDirectory()) {
			throw new IllegalArgumentException(srcDir.getAbsolutePath()
					+ " 不是目录！");
		}
		ZipArchiveOutputStream zip = null;
		try {
			zip = new ZipArchiveOutputStream(destFile);
			File[] files = srcDir.listFiles();
			for (File f : files) {
				addZipEntry(null, f, zip);
			}
		} finally {
			IOUtils.closeQuietly(zip);
		}
	}
	
	public static void extractZip(File zipFile,File destDir)throws IOException{
		if(!destDir.isDirectory()){
			throw new IllegalArgumentException(destDir.getAbsolutePath()
					+ " 不是目录！");
		}
		
		ZipArchiveInputStream zip = null;
		try{
			zip = new ZipArchiveInputStream(new FileInputStream(zipFile));
			ZipArchiveEntry entry = null;
			while((entry = zip.getNextZipEntry()) != null){
				File targetFile = new File(destDir,entry.getName());
				if(!targetFile.getParentFile().exists() || !targetFile.getParentFile().isDirectory()){
					targetFile.getParentFile().mkdirs();
				}
				
				FileOutputStream out = new FileOutputStream(targetFile);
				IOUtils.copy(zip, out);
				IOUtils.closeQuietly(out);
			}
		}finally{
			IOUtils.closeQuietly(zip);
		}
	}

	public static String[] listZip(File zipFile) throws IOException {
		if (zipFile == null) {
			return null;
		}

		if (!zipFile.exists() || !zipFile.isFile()) {
			throw new IllegalArgumentException(zipFile.getAbsolutePath()
					+ " 不是合法的文件！");
		}

		ZipArchiveInputStream zip = null;
		try {
			zip = new ZipArchiveInputStream(new FileInputStream(zipFile));
			List<String> entrys = new LinkedList<String>();
			ZipArchiveEntry entry;
			while ((entry = zip.getNextZipEntry()) != null) {
				if (!entry.isDirectory()) {
					entrys.add(entry.getName());
				}
			}
			return entrys.toArray(new String[entrys.size()]);
		} finally {
			IOUtils.closeQuietly(zip);
		}
	}

	private static void addZipEntry(String parentEntryName, File file,
			ZipArchiveOutputStream zip) throws IOException {
		String name = file.getName();
		if (parentEntryName != null) {
			name = parentEntryName + "/" + file.getName();
		}
		if (file.isFile()) {
			ZipArchiveEntry entry = new ZipArchiveEntry(name);
			entry.setSize(file.length());

			zip.putArchiveEntry(entry);
			BufferedInputStream in = new BufferedInputStream(
					new FileInputStream(file));

			byte[] buffer = new byte[2048];
			int count = 0;
			while ((count = in.read(buffer)) > 0) {
				zip.write(buffer, 0, count);
			}
			zip.closeArchiveEntry();
			in.close();
		} else if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (File f : files) {
				addZipEntry(name, f, zip);
			}
		}
	}
}
